
#ifndef RAIS_LIBDEF_H
#define RAIS_LIBDEF_H
/*
	Rais_LibDef.h : A util lib fase to libraries.
	Most of these things are come from Rais_Utils.h(this is fase to user, not suitable for libraries)
	there are all I needs.

	Created: 2020.7.31
	by Raiscies.

*/

namespace rais{

using uint8_t = unsigned char; 	//using in template need to be declared explicit(exactly, this type's name is rais::uint8_t...).
using len_t = unsigned int;
using idx_t = long;

template <typename Ret, typename... Args>
using func_ptr = Ret(*)(Args...);

//disable a unused var's warning
#ifndef unused
#define unused(var) static_cast<void>(var)
#endif


//remove a type or a type of variable's pointer or reference feature 
template <typename T> struct Rem_rp     {using type = T;};
template <typename T> struct Rem_rp<T*> {using type = T;};
template <typename T> struct Rem_rp<T&> {using type = T;};
template <typename T> struct Rem_rp<T&&>{using type = T;};
template <typename T> using rem_rp = typename Rem_rp<T>::type;


//some frequently-used functions:

//my move function!
template <typename T>
inline auto move(T&& a)-> rem_rp<T>&& {
    return    static_cast<rem_rp<T>&&>(a);
}

//constrain a value between lower-bound and upper-bound
template <typename CT, typename VT>
inline constexpr VT clamp(const CT& lower, const VT& val, const CT& upper){return val < lower ? lower : (val > upper ? upper : val);}

//swap two variables
template <bool isInteger = false, typename T>
inline void swap(T& a, T& b){
	if(isInteger) a ^= b ^= a ^= b;
	else {
		T tmp = a;
		a = b;
		b = tmp;
	}
}


}

#endif